var DatasettingsAssistant = Class.create({
	
	initialize: function(params) {
		this.settingsModel = { };
		
		this.params = params;
		this.appAssistant = Mojo.Controller.getAppController().assistant;
		
		if (this.params) {
			this.firstuse = this.params.callingapp == 'firstuse';
			this.initialCategory = this.params.category;
		}
		
		this.updateSettings = this.updateSettings.bind(this);
		this.onDataFieldChange = this.onFieldChange.bind(this, "dataDirty");
		this.onMmsFieldChange = this.onFieldChange.bind(this, "mmsDirty");
		this.onCategoryChange = this.onCategoryChange.bind(this);
		this.onDataChangeTap = this.onDataChangeTap.bind(this);
		this.onDataSetupAnywayTap = this.onDataSetupAnywayTap.bind(this);
		this.onMmsChangeTap = this.onMmsChangeTap.bind(this);
		this.onMmsSetupAnywayTap = this.onMmsSetupAnywayTap.bind(this);
		this.onTestDataSettings = this.onTestDataSettings.bind(this);
		this.onWriteDataSettings = this.onWriteDataSettings.bind(this);
		this.onTestMmsSettings = this.onTestMmsSettings.bind(this);
		this.onTestMmsApnResult = this.onTestMmsApnResult.bind(this);
		this.onWriteMmsSettings = this.onWriteMmsSettings.bind(this);
		this.writeDataSettings = this.writeDataSettings.bind(this); 
		this.writeMmsSettings = this.writeMmsSettings.bind(this); 
		this.onEmergencyTap = this.onEmergencyTap.bind(this);
		
		this.testCallbacks = {};
		this.firstField = {};
		
		this.testCallbacks.data = this.onDataChangeTap;
		this.testCallbacks.mms = this.onMmsChangeTap;
		
		this.loadSettings();
	},
	
	// block back gesture in first use
	handleCommand: function(event){
		if (event.type == Mojo.Event.back && PalmSystem.isMinimal === true) {
			event.stopPropagation();
			Event.stop(event);
		}
	},
	
	setup: function() {
		if(this.firstuse){
			this.bodyClassName = this.controller.document.body.className;
			this.controller.document.body.className = "firstuse";
			$('mojo-scene-datasettings').addClassName('palm-dark');
			$('categoryToggle').hide();
			$('firstuseheader').show();
			$('firstuse_emergency').show();
			$('glass-background').show();
			Mojo.Event.listen($('firstuse_emergency'),Mojo.Event.tap, this.onEmergencyTap);
		} 
		
		this.controller.setupWidget('categoryToggle',
			this.categoryToggleAttrib = {
				choices: [
					{label:$L("Internet APN"), value:"data"},
					{label:$L("MMS APN"), value:"mms"}
				]
			},
			this.categoryToggleModel = {
				value: this.initialCategory || 'data',
				disabled: false
			}
		);
		
		Mojo.Event.listen($('categoryToggle'), Mojo.Event.propertyChange, this.onCategoryChange);
	
		this.controller.setupWidget('dataChange',
			{
				type: Mojo.Widget.activityButton
			},
			this.dataChangeModel = {
				label: $L("Change Settings")				
			}
		);
		
		Mojo.Event.listen($("dataChange"),Mojo.Event.tap, this.onDataChangeTap);
		
		this.controller.setupWidget('dataSetupAnyway',
			{
				label: $L("Set Up Anyway")
			}, { }
		);
		
		Mojo.Event.listen($("dataSetupAnyway"),Mojo.Event.tap, this.onDataSetupAnywayTap);
		
		this.controller.setupWidget('mmsChange',
			{
				type: Mojo.Widget.activityButton
			},
			this.mmsChangeModel = {
				label: $L("Change Settings")				
			}
		);
		
		Mojo.Event.listen($("mmsChange"),Mojo.Event.tap, this.onMmsChangeTap);
		
		this.controller.setupWidget('mmsSetupAnyway',
			{
				label: $L("Set Up Anyway")
			}, { }
		);
		
		Mojo.Event.listen($("mmsSetupAnyway"),Mojo.Event.tap, this.onMmsSetupAnywayTap);

		this.controller.setupWidget('dataApn', {
			modelProperty: "dataApn",
			autoReplace: false,
			textCase: Mojo.Widget.steModeLowerCase
		}, this.settingsModel);
		
		Mojo.Event.listen($('dataApn'), Mojo.Event.propertyChange, this.onDataFieldChange);
		
		this.controller.setupWidget('dataUser', {
			modelProperty: "dataUser",
			autoReplace: false,
			textCase: Mojo.Widget.steModeLowerCase
		}, this.settingsModel);
	
		Mojo.Event.listen($('dataUser'), Mojo.Event.propertyChange, this.onDataFieldChange);

		this.controller.setupWidget('dataPassword', {
			modelProperty: "dataPassword",
			autoReplace: false
		}, this.settingsModel);
		
		Mojo.Event.listen($('dataPassword'), Mojo.Event.propertyChange, this.onDataFieldChange);
		
		this.controller.setupWidget('mmsApn', {
			modelProperty: "mmsApn",
			autoReplace: false,
			textCase: Mojo.Widget.steModeLowerCase
		}, this.settingsModel);
		
		Mojo.Event.listen($('mmsApn'), Mojo.Event.propertyChange, this.onMmsFieldChange);
		
		this.controller.setupWidget('mmsUser', {
			modelProperty: "mmsUser",
			autoReplace: false,
			textCase: Mojo.Widget.steModeLowerCase
		}, this.settingsModel);

		Mojo.Event.listen($('mmsUser'), Mojo.Event.propertyChange, this.onMmsFieldChange);

		this.controller.setupWidget('mmsPassword', {
			modelProperty: "mmsPassword",
			autoReplace: false
		}, this.settingsModel);
		
		Mojo.Event.listen($('mmsPassword'), Mojo.Event.propertyChange, this.onMmsFieldChange);
		
		this.controller.setupWidget('mmsc', {
			modelProperty: "mmsc",
			autoReplace: false,
			textCase: Mojo.Widget.steModeLowerCase
		}, this.settingsModel);
		
		Mojo.Event.listen($('mmsc'), Mojo.Event.propertyChange, this.onMmsFieldChange);
		
		this.controller.setupWidget('mmsProxy', {
			modelProperty: "mmsProxy",
			autoReplace: false,
			textCase: Mojo.Widget.steModeLowerCase
		}, this.settingsModel);
		
		Mojo.Event.listen($('mmsProxy'), Mojo.Event.propertyChange, this.onMmsFieldChange);
		
		this.controller.setupWidget('mmsMaxSize', {
			modelProperty: "mmsMaxSize",
			autoReplace: false,
			modifierState: Mojo.Widget.numLock,
			charsAllow: Mojo.Char.isDigit,
			textCase: Mojo.Widget.steModeLowerCase
		}, this.settingsModel);
		
		Mojo.Event.listen($('mmsMaxSize'), Mojo.Event.propertyChange, this.onMmsFieldChange);
		
		this.firstField.data = $('dataApn');
		this.firstField.mms = $('mmsApn');
		
		if (this.initialCategory) {
			this.onCategoryChange.defer(null, true /* force */);
		}
		
		this.controller.listen(this.controller.sceneElement, Mojo.Event.keypress, this.handleKeyPressEvent.bind(this));
	},
	
	loadSettings: function() {
		this.manualDataGetRequest = SystemService.getManualDataSettings(this.updateSettings);
	},
	
	updateSettings: function(payload) {
		
		if (payload && payload.apns) {
			
			var d;
			var m;
			
			// find the data and/or mms apn in the list
			payload.apns.each(function(apn) {
				if (apn.apnid === DatasettingsAssistant.kApnTypeData) {
					d = apn;
				} else if (apn.apnid === DatasettingsAssistant.kApnTypeMms) {
					m  = apn;
				}
			});
			
			// if we have a data apn, get the settings
			if (d !== undefined) {
				this.settingsModel.dataApn = d.apn;
				this.settingsModel.dataUser = d.cshnUserName;
				this.settingsModel.dataPassword = d.cshnPassword;
			}
			
			// if we have an mms apn, get those settings too
			if (m !== undefined) {
				this.settingsModel.mmsApn = m.apn;
				this.settingsModel.mmsUser = m.cshnUserName;
				this.settingsModel.mmsPassword = m.cshnPassword;
			}
				
			this.settingsModel.mmsc = payload.mmscUrl;
			this.settingsModel.mmsProxy = payload.mmsProxy;
			this.settingsModel.mmsMaxSize = payload.mmscMessageSizeLimit;
			
		} else {
			this.settingsModel.dataApn = '';
			this.settingsModel.dataUser = '';
			this.settingsModel.dataPassword = '';
			
			this.settingsModel.mmsApn = '';
			this.settingsModel.mmsUser = '';
			this.settingsModel.mmsPassword = '';
			
			this.settingsModel.mmsc = '';
			this.settingsModel.mmsProxy = '';
			this.settingsModel.mmsMaxSize = '';
		}
		
		this.controller.modelChanged(this.settingsModel);
	},
	
	// set bound flag to true if a text field changed
	onFieldChange: function(flag, event) {
		if (event.oldValue !== event.value) {
			this[flag] = true;
		}
	},
	
	buttonSpin: function(button, model) {
		model.label = $L("Changing Settings");
		model.disabled = true;
		this.controller.modelChanged(model);
		button.mojo.activate();
	},
	
	buttonSpinStop: function(button, model, success) {
		model.label = $L("Change Settings");
		model.disabled = false;
		this.controller.modelChanged(model);
		button.mojo.deactivate();
	},
	
	onDataChangeTap: function() {
		this.testDataSettings();
		this.buttonSpin($('dataChange'), this.dataChangeModel);
	},
	
	onDataSetupAnywayTap: function() {
		this.testFailedDialog($L("If these settings are invalid, you will not have a data connection.  Are you sure you want to use these settings?"), this.writeDataSettings);
	},
	
	testDataSettings: function() {
		this.manualDataTestRequest = SystemService.testManualDataSettings({
			username: this.settingsModel.dataUser,
			password: this.settingsModel.dataPassword,
			apn: this.settingsModel.dataApn,
			disconnect: true
		}, this.onTestDataSettings);
	},
	
	onTestDataSettings: function(success, payload) {
		if (success) {
			this.writeDataSettings();
		} else {
			this.buttonSpinStop($('dataChange'), this.dataChangeModel, false);
			
			if (this.firstUse) {
				this.controller.showAlertDialog({
					onChoose: function() { },
					title: $L("Unable to Set Up Internet APN"),
					message: $L("Your settings could not be validated. If you believe these settings are correct, try again in a few minutes. For assistance, call your service provider."),
					choices: [
						{
							label: $L("OK"),
							type: 'affirmative',
							value: 'OK'
						}
					]
				});
			} else {
				this.showError('data', $L("Invalid Internet APN Settings."));
			}			
		} 
	},
	
	writeDataSettings: function() {
		Mojo.Log.info("WRITING DATA SETTINGS!");
		this.manualDataSetRequest = SystemService.setManualDataSettings({
			"apns": [{
				"apn": this.settingsModel.dataApn,
				"username": this.settingsModel.dataUser,
				"password": this.settingsModel.dataPassword,
				"apnType": DatasettingsAssistant.kApnTypeData
			}]
		}, this.onWriteDataSettings);
	},
	
	onWriteDataSettings: function(success) {
		this.buttonSpinStop($('dataChange'), this.dataChangeModel, true);
		if (success) {
			this.resetError('data');
			this.dataDirty = false;
			SystemService.enableManualDataSettings(true);
			if(this.firstuse) {
				this.controller.window.close();
			} else {
				Mojo.Controller.appController.showBanner({
					icon: "images/notification-small-handset.png",
					messageText: $L("Internet APN settings changed"),
					soundClass: 'none'
				}, {}, '');
				
			}
		} else {
			this.showError('data', $L("Unable to Write Settings."));
			
		}
	},
	
	showError: function(category, text) {
		if (!this.firstuse) {
			$(category + 'SetupAnyway').show();
		}
		
		$(category + 'Error').show();
		$(category + 'ErrorText').textContent = text;
	},
	
	resetError: function(category) {
		$(category + 'SetupAnyway').hide();
		$(category + 'Error').hide();
	},
	
	onMmsChangeTap: function() {
		this.testMmsSettings();
		this.buttonSpin($('mmsChange'), this.mmsChangeModel, true);
	},
	
	onMmsSetupAnywayTap: function() {
		this.testFailedDialog($L("If these settings are invalid, you will not be able to send or receive an MMS.  Are you sure you want to use these settings?"), this.writeMmsSettings);
	},
	
	// to test MMS settings, we need to manage setting up the MMS APN and tearing it down
	testMmsSettings: function() {
		this.mmsApnRequest = SystemService.testManualDataSettings({
			username: this.settingsModel.mmsUser,
			password: this.settingsModel.mmsPassword,
			apn: this.settingsModel.mmsApn
		}, this.onTestMmsApnResult);
		
	},
	
	onTestMmsApnResult: function(success) {
		Mojo.Log.info("onTestMmsApnResult", success);
		if (success) {
			this.mmsTestRequest = SystemService.testMmsSettings({
				"mmsc": this.settingsModel.mmsc,
				"mmsProxy": this.settingsModel.mmsProxy
			}, this.onTestMmsSettings);
		} else { // on failure, tear down
			SystemService.testDataSettingsDisconnect();
			this.showError('mms', $L("Invalid MMS APN Settings."));
			this.buttonSpinStop($('mmsChange'), this.mmsChangeModel);
		}
	},
	
	onTestMmsSettings: function(success) {
		SystemService.testDataSettingsDisconnect();
		if (success) {
			this.writeMmsSettings();
		} else {
			this.showError('mms', $L("Invalid MMS Settings."));
			this.buttonSpinStop($('mmsChange'), this.mmsChangeModel);
		}
	},
	
	writeMmsSettings: function() {
		this.mmsSetRequest = SystemService.setManualDataSettings({
			"apns": [{
				"apn": this.settingsModel.mmsApn,
				"username": this.settingsModel.mmsUser,
				"password": this.settingsModel.mmsPassword,
				"apnType": DatasettingsAssistant.kApnTypeMms
			}],
			"mmsSettings": {
				"mmscUrl": this.settingsModel.mmsc,
				"mmsProxy": this.settingsModel.mmsProxy,
				"mmscMessageSizeLimit": this.settingsModel.mmsMaxSize
			}
		}, this.onWriteMmsSettings);
	},
	
	onWriteMmsSettings: function(success) {
		this.buttonSpinStop($('mmsChange'), this.mmsChangeModel);
		if (success) {
			Mojo.Controller.appController.showBanner(
				{
					icon: "images/notification-small-handset.png",
					messageText: $L("MMS APN settings changed"),
					soundClass: 'none'
				}, 
				{},'');
			this.resetError('mms');
			this.mmsDirty = false;
			SystemService.enableManualDataSettings(true);
		} else {
			this.showError('mms', $L("Unable to write settings."));
		}		
	},
	
	onCategoryChange: function(event, force) {
		var newCategory = this.categoryToggleModel.value;
		var oldCategory = (newCategory === 'data' ? 'mms' : 'data');
		
		if (!force && this[oldCategory + 'Dirty']) {
			this.saveDialog(oldCategory);
			return;
		}
		
		$(oldCategory).hide();
		$(newCategory).show();
		this.resetError(oldCategory);				
		
		this[oldCategory + 'Dirty'] = false;

		// workaround dialog box closing animation blocking focus event.
		if (force) {
			this.firstField[newCategory].mojo.focus.delay(0.5);
		} else {
			this.firstField[newCategory].mojo.focus.defer();
		}
		
		this.loadSettings();
	},
	
	saveDialog: function(oldCategory) {
		this.controller.showAlertDialog({
			onChoose: this.onSaveDialogChoice.bind(this, oldCategory),
			message: $L("You must save changes before continuing."),
			choices: [
				{
					label: $L("Save Changes"),
					type: 'affirmative',
					value: 'SAVE'
				},
				{
					label: $L("Discard Changes"),
					type: 'negative',
					value: 'DISCARD'
				},
				{
					label: $L("Cancel"),
					type: 'dismiss',
					value: 'CANCEL'
				}
			]
		});
	},
	
	onSaveDialogChoice: function(oldCategory, choice) {
		switch(choice) {
			case 'DISCARD':
				this.onCategoryChange(null, true /* force */);
				break;
			case 'SAVE':
				this.testCallbacks[oldCategory]();
				// falls through
			default:
				this.categoryToggleModel.value = oldCategory;
				this.controller.modelChanged(this.categoryToggleModel);
				break;
			}
	},
	
	testFailedDialog: function(prompt, callback) {
		this.controller.showAlertDialog({
            	onChoose: this.onTestFailedDialogChoice.bind(this, callback),
            	title: $L("Set Up Anyway?"),
				message: prompt,
				choices: [
					{
                		label: $L('Set Up Anyway'),
						type: 'affirmative',
                		value: 'OK'
            		}, {
                		label: $L('Cancel'),
						type: 'dismiss',
                		value: 'CANCEL'
            		}
				]
        });
	},
	
	onTestFailedDialogChoice: function(callback, value) {
		if (value === 'OK') {
			callback();
		}
	},
	
	onEmergencyTap: function() {
		this.controller.popupSubmenu({
  			onChoose: function(value) {
				if ( "emergency" === value ) {
					this.emergencyDial();
				}
			}.bind(this),
  			placeNear: this.controller.get('firstuse_emergency_menu_anchor'),
			items: [
				{label: $L('Emergency call'), command: 'emergency'}, 
				{label: $L('Cancel'), command: 'cancel'}
			]
		});
	},
	
	emergencyDial: function(number) {
		if ( ! number ) {
			number = this.appAssistant.emergencyNumbers.first();
		}
		var r = new Mojo.Service.Request("palm://com.palm.applicationManager/open", {
			parameters: {
				id: 'com.palm.app.phone',
				params: {
					"prefill": number,
					"locale": Mojo.Locale.current,
					"firstuse": this.firstuse
				}
			}
	    });
	},
	
	handleKeyPressEvent: function(event) {
		// only capture if nothing else has focus
		if ( Mojo.View.getFocusedElement(this.controller.sceneElement) ) {
			return;
		}
		
		var eventChar = String.fromCharCode(event.originalEvent.keyCode);
		
		if ( ! this.previousKeyPressed ) {
			this.previousKeyPressed = new Array(4);
		}
		this.previousKeyPressed.shift();
		this.previousKeyPressed.push(eventChar);
		
		var value = this.previousKeyPressed.join("");
		this.appAssistant.emergencyNumbers.find(function(number) {
			if ( value.endsWith(number) ) {
				this.emergencyDial(number);
				delete this.previousKeyPressed;
				return true;
			}
		},this);
	}
});

DatasettingsAssistant.kApnTypeData = 1;
DatasettingsAssistant.kApnTypeMms = 4;
